package com.example.moneygrosService.database;

import java.util.Arrays;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;

import com.example.moneygrosService.database.MoneyContract.Balances;
import com.example.moneygrosService.database.MoneyContract.Pendings;
import com.example.moneygrosService.database.MoneyContract.UserProfiles;
import com.example.moneygrosService.database.MoneyContract.Users;
import com.example.moneygrosService.database.MoneyDatabase.Tables;
import com.example.moneygrosService.utils.SelectionBuilder;

public class MoneyProvider extends ContentProvider {

	private static final String TAG = "MoneyProvider";
    private static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);


    private MoneyDatabase mOpenHelper;
    
    private static final UriMatcher sUriMatcher = buildUriMatcher();

    private static final int BALANCES = 100;
    private static final int BALANCES_ID = 101;

    private static final int USERS = 200;
    private static final int USERS_ID = 201;

    private static final int USER_PROFILES = 300;
    private static final int USER_PROFILES_ID = 301;
    
    private static final int PENDINGS = 400;
    private static final int PENDINGS_ID = 401;
  
    
    /**
     * Build and return a {@link UriMatcher} that catches all {@link Uri}
     * variations supported by this {@link ContentProvider}.
     */
    private static UriMatcher buildUriMatcher() {
       
    	final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        final String authority = MoneyContract.CONTENT_AUTHORITY;
       
        matcher.addURI(authority, "balances", BALANCES);
        matcher.addURI(authority, "balances/*", BALANCES_ID);

        matcher.addURI(authority, "users", USERS);
        matcher.addURI(authority, "users/*", USERS_ID);

        matcher.addURI(authority, "user_profiles", USER_PROFILES);
        matcher.addURI(authority, "user_profiles/*", USER_PROFILES_ID);

        matcher.addURI(authority, "pendings", PENDINGS);
        matcher.addURI(authority, "pendings/*", PENDINGS_ID);
       
        return matcher;
    }
    
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
        if (LOGV) Log.v(TAG, "delete(uri=" + uri + ")");
        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        final SelectionBuilder builder = buildSimpleSelection(uri);
        int retVal = builder.where(selection, selectionArgs).delete(db);
        getContext().getContentResolver().notifyChange(uri, null);
        return retVal;
	}

	@Override
	public String getType(Uri uri) {
        final int match = sUriMatcher.match(uri);
        switch (match) {
            case BALANCES:
                return Balances.CONTENT_TYPE;
            case BALANCES_ID:
                return Balances.CONTENT_ITEM_TYPE;
            case USERS: 
                return Users.CONTENT_TYPE;
            case USERS_ID:
                return Users.CONTENT_ITEM_TYPE;
            case USER_PROFILES:
                return UserProfiles.CONTENT_TYPE;
            case USER_PROFILES_ID:
                return UserProfiles.CONTENT_ITEM_TYPE;
            case PENDINGS:
                return Pendings.CONTENT_TYPE;
            case PENDINGS_ID:
                return Pendings.CONTENT_ITEM_TYPE;
            default:
                throw new UnsupportedOperationException("Unknown uri: " + uri);
        }
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
        if (LOGV) Log.v(TAG, "insert(uri=" + uri + ", values=" + values.toString() + ")");

         Log.v(TAG, "openHelper" +  mOpenHelper + ")");
        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        Log.v(TAG, "database" +  db.toString() + ")");

        final int match = sUriMatcher.match(uri);
        switch (match) {
            case BALANCES: {
                db.insertOrThrow(Tables.BALANCES, null, values);
                getContext().getContentResolver().notifyChange(uri, null);
                return Balances.buildUri(values.getAsString(Balances._ID));
            }
            case USERS: {
                db.insertOrThrow(Tables.USERS, null, values);
                getContext().getContentResolver().notifyChange(uri, null);
                return Users.buildUri(values.getAsString(Users._ID));
            }
            case USER_PROFILES: {
                db.insertOrThrow(Tables.USER_PROFILES, null, values);
                getContext().getContentResolver().notifyChange(uri, null);
                return UserProfiles.buildUri(values.getAsString(UserProfiles._ID));
            }
            case PENDINGS: {
                db.insertOrThrow(Tables.PENDINGS, null, values);
                getContext().getContentResolver().notifyChange(uri, null);
                return Pendings.buildUri(values.getAsString(Pendings._ID));
            }
            default: {
                throw new UnsupportedOperationException("Unknown uri: " + uri);
            }
        }
	}

	@Override
	public boolean onCreate() {
		
        Log.v("TATA", "MoneyProvider creation" );
        final Context context = getContext();
        mOpenHelper = new MoneyDatabase(context);
        Log.v("TATA", "MoneyProvider creation: mOpenHelper"+ mOpenHelper);
        Log.v("TATA", "MoneyProvider creation: mOpenHelper"+ mOpenHelper.toString());

        return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {

    	if (LOGV) Log.v(TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")");
        Log.v(TAG, "openHelper" +  mOpenHelper + ")");

        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();

        final int match = sUriMatcher.match(uri);
        switch (match) {
            default: {
                // Most cases are handled with simple SelectionBuilder
                final SelectionBuilder builder = buildSimpleSelection(uri);
                return builder.where(selection, selectionArgs).query(db, projection, sortOrder);
            }
         
        }
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
        if (LOGV) Log.v(TAG, "update(uri=" + uri + ", values=" + values.toString() + ")");
        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        final SelectionBuilder builder = buildSimpleSelection(uri);
        int retVal = builder.where(selection, selectionArgs).update(db, values);
        getContext().getContentResolver().notifyChange(uri, null);
        return retVal;
	}



	private SelectionBuilder buildSimpleSelection(Uri uri) {
		final SelectionBuilder builder = new SelectionBuilder();
		final int match = sUriMatcher.match(uri);
		switch (match) {
		case BALANCES: {
			return builder.table(Tables.BALANCES);
		}     
		case BALANCES_ID: {
			return builder.table(Tables.BALANCES).where(Balances._ID + "=?", Balances.getId(uri));
		}
		case USERS: {
			return builder.table(Tables.USERS);
		}     
		case USERS_ID: {
			return builder.table(Tables.USERS).where(Users._ID + "=?", Users.getId(uri));
		}
		case USER_PROFILES: {
			return builder.table(Tables.USER_PROFILES);
		}     
		case USER_PROFILES_ID: {
			return builder.table(Tables.USER_PROFILES).where(Users._ID + "=?", Users.getId(uri));
		}
		case PENDINGS: {
			return builder.table(Tables.PENDINGS);
		}     
		case PENDINGS_ID: {
			return builder.table(Tables.PENDINGS).where(Pendings._ID + "=?", Pendings.getId(uri));
		}
		default: {
			throw new UnsupportedOperationException("Unknown uri: " + uri);
		}
		}
	}

}
